//
// Created by 30938 on 2022/8/29.
//
#include <iostream>
#include <vector>
#include <string>
#include <fstream>

using namespace std;

class CutCopyFile {
private:
    string fileName;
    streamsize totalSize;
    streamsize oneSize;
    streamsize fileNum;
    vector<string> arr;
public:
    CutCopyFile(const string &fileName, const streamsize &oneSize) {
        this->fileName = fileName;

        ifstream ifs(fileName, ios::binary);
        ifs.seekg(0, ios::end);
        this->totalSize = ifs.tellg();
        ifs.close();

        this->oneSize = oneSize;
        this->fileNum = this->totalSize / oneSize;

        //vector<string> arr = {0};
    }

    void copyFileTo(const string &copyFileName) {
        ifstream ifs(fileName, ios::binary);
        for (int i = 1; i <= fileNum + 1; ++i) {
            char temp[256] = {0};
            sprintf(temp, "%s(%d).exe", copyFileName.c_str(), i);
            string copyFileNameNext = temp;
            ofstream ofs(copyFileNameNext, ios::binary);

            streamsize copiedSize = ifs.tellg();

            if (copiedSize >= totalSize) {
                return;
            }

            ifs.seekg(copiedSize, ios::beg);

            while (!ifs.eof()) {
                char buffer[1024 * 8] = {0};
                ifs.read(buffer, sizeof(buffer));
                streamsize size = ifs.gcount();  //  判断本次
                 // 读了多少个
                ofs.write(buffer, size);
                ofs.flush();
                streamsize curSize = ofs.tellp();
                printf("总大小%.2fMB，已复制%.2fMB，当前进度%.2f%%\n", (float) totalSize / 1024 / 1024,
                       (float) (curSize+(i-1)*oneSize) / 1024 / 1024,
                       ((float) (curSize+(i-1)*oneSize)/ (float) totalSize) * 100);

                if (curSize > oneSize) {
                    break;
                }
            }
            arr.push_back(copyFileNameNext);
            ofs.close();
        }
        ifs.close();
        cout << "===========================================" << endl;
        cout << "复制完成" << endl;
    }

    void mergeFileTo(const string &mergeFileName) {
        ofstream ofs(mergeFileName, ios::binary | ios::app);
        for (auto &i: arr) {
            ifstream ifs(i, ios::binary);
            while (!ifs.eof()) {
                char buffer[1024 * 8] = {0};
                ifs.read(buffer, sizeof(buffer));
                streamsize size = ifs.gcount();
                ofs.write(buffer, size);
                ofs.flush();
            }
            ifs.close();
        }
        ofs.close();
        cout << "合并完成" << endl;
    }
};

void test01() {
    CutCopyFile file("E:\\SOFTWAER\\c++\\clion\\CLion-2021.3.4.exe", 1024 * 1024 * 100);

    file.copyFileTo("E:\\SOFTWAER\\c++\\clion\\cut");

    file.mergeFileTo("E:\\SOFTWAER\\c++\\clion\\cut\\21342131.exe");
}

int main() {
    setbuf(stdout, nullptr);
    test01();
    return 0;
}


